<!--
 * Copyright © 2022
 * @Author: zhangxiang
 * @Date: 2022-10-26 15:14:16
 * @LastEditors: zhangxiang
 * @LastEditTime: 2023-09-21 15:07:46
 * @Description:
 *
-->

<template>
  <el-dialog
    class="scaling-policy-dialog"
    :title="title"
    :visible="show"
    width="730px"
    top="5vh"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    @close="closeClick"
  >
    <el-row type="flex" align="middle">
      <el-button
        size="small"
        type="primary"
        icon="el-icon-plus"
        plain
        :disabled="showPolicyMax || scene == 3"
        @click="addPolicyClick('max')"
      >新增扩容策略</el-button>
      <el-button
        size="small"
        type="primary"
        icon="el-icon-plus"
        :disabled="showPolicyMin || scene == 3"
        @click="addPolicyClick('min')"
      >新增缩容策略</el-button>
    </el-row>
    <!-- 扩容策略 -->
    <div v-if="showPolicyMax" class="wrapper">
      <el-row type="flex" align="middle">
        <div>扩容策略</div>
        <el-button
          size="mini"
          type="danger"
          style="margin-left: auto"
          :disabled="scene == 3"
          @click="deletePolicyClick('max')"
        >删除</el-button>
      </el-row>
      <el-divider class="divider" />
      <el-form
        ref="formMax"
        class="form"
        :rules="rules"
        :model="formMax"
        label-width="auto"
        size="small"
      >
        <!-- 触发条件 -->
        <el-form-item label="触发条件" prop="triggerCondition">
          <el-row type="flex" align="middle">
            <!-- 查看模式不能编辑 -->
            <el-select
              v-model="formMax.resource"
              placeholder="请选择"
              style="width: 200px"
              :disabled="scene == 3"
            >
              <el-option
                v-for="item in resourceOptions"
                :key="item.value"
                :label="item.lable"
                :value="item.value"
              />
            </el-select>
            <div class="text">最大值大于</div>
            <!-- 查看模式不能编辑 -->
            <el-input
              v-model="formMax.value"
              placeholder="请输入"
              style="width: 200px"
              :disabled="scene == 3"
            >
              <template slot="append">%</template>
            </el-input>
          </el-row>
        </el-form-item>
        <el-form-item label="监控周期(min)" prop="duration">
          <el-row type="flex" align="middle">
            <!-- 查看模式不能编辑 -->
            <el-select
              v-model="formMax.duration"
              placeholder="输入"
              style="width: 200px"
              :disabled="scene == 3"
            >
              <el-option
                v-for="item in durationOptions"
                :key="item.value"
                :label="item.lable"
                :value="item.value"
              />
            </el-select>
            <i
              class="el-icon-info icon"
              style="color: #c3c3c3; font-size: 16px; margin: 0 5px 0 10px"
            ></i>
            <span class="hint">监控并刷新当前指标采样值信息</span>
          </el-row>
        </el-form-item>
        <el-form-item label="连续出现次数" prop="continuousNum">
          <el-row type="flex" align="middle">
            <!-- 查看模式不能编辑 -->
            <el-input-number
              v-model="formMax.continuousNum"
              placeholder="请输入"
              style="width: 200px"
              :min="1"
              :precision="0"
              :disabled="scene == 3"
            />
            <i
              class="el-icon-info icon"
              style="color: #c3c3c3; font-size: 16px; margin: 0 5px 0 10px"
            ></i>
            <span class="hint">连续n个监控周期的采样值全部满足触发条件</span>
          </el-row>
        </el-form-item>
        <el-form-item label="执行动作" prop="num">
          <el-row type="flex" align="middle">
            <div class="text" style="margin-left: 0">增加</div>
            <!-- 查看模式不能编辑 -->
            <el-input-number
              v-model="formMax.num"
              placeholder="请输入"
              style="width: 160px"
              :min="1"
              :max="maxNumUpper - 1"
              :precision="0"
              :disabled="scene == 3 || scene == 2"
            />
            <div class="text" style="margin-right: 0">个实例</div>
            <i
              class="el-icon-info icon"
              style="color: #c3c3c3; font-size: 16px; margin: 0 5px 0 10px"
            ></i>
            <span class="hint">一次最多可以触发该伸缩组配置最大VM数-1</span>
          </el-row>
        </el-form-item>
        <el-form-item label="冷却时间(s)" prop="coolTime">
          <el-row type="flex" align="middle">
            <!-- 查看模式不能编辑 -->
            <el-input
              v-model="formMax.coolTime"
              placeholder="请输入"
              style="width: 200px; flex-shrink: 0"
              :disabled="scene == 3"
            />
            <i
              class="el-icon-info icon"
              style="color: #c3c3c3; font-size: 16px; margin: 0 5px 0 10px"
            ></i>
            <span
              class="hint"
            >每次伸缩完成之后，系统计算冷区时间，在此期间内拒绝再次触发伸缩活动</span>
          </el-row>
        </el-form-item>
      </el-form>
    </div>
    <!-- 缩容策略 -->
    <div v-if="showPolicyMin" class="wrapper">
      <el-row type="flex" align="middle">
        <div>缩容策略</div>
        <el-button
          size="mini"
          type="danger"
          style="margin-left: auto"
          :disabled="scene == 3"
          @click="deletePolicyClick('min')"
        >删除</el-button>
      </el-row>
      <el-divider class="divider" />
      <el-form
        ref="formMin"
        class="form"
        :rules="rules"
        :model="formMin"
        label-width="auto"
        size="small"
      >
        <el-form-item label="触发条件" prop="triggerCondition2">
          <el-row type="flex" align="middle">
            <el-select
              v-model="formMin.resource"
              placeholder="请选择"
              style="width: 200px"
              :disabled="scene == 3"
            >
              <el-option
                v-for="item in resourceOptions"
                :key="item.value"
                :label="item.lable"
                :value="item.value"
              />
            </el-select>
            <div class="text">最小值小于</div>
            <el-input
              v-model="formMin.value"
              placeholder="请输入"
              style="width: 200px"
              :disabled="scene == 3"
            >
              <template slot="append">%</template>
            </el-input>
          </el-row>
        </el-form-item>
        <el-form-item label="监控周期(min)" prop="duration">
          <el-row type="flex" align="middle">
            <el-select
              v-model="formMin.duration"
              placeholder="输入"
              style="width: 200px"
              :disabled="scene == 3"
            >
              <el-option
                v-for="item in durationOptions"
                :key="item.value"
                :label="item.lable"
                :value="item.value"
              />
            </el-select>
            <i
              class="el-icon-info icon"
              style="color: #c3c3c3; font-size: 16px; margin: 0 5px 0 10px"
            ></i>
            <span class="hint">监控并刷新当前指标采样值信息</span>
          </el-row>
        </el-form-item>
        <el-form-item label="连续出现次数" prop="continuousNum">
          <el-row type="flex" align="middle">
            <el-input-number
              v-model="formMin.continuousNum"
              placeholder="请输入"
              style="width: 200px"
              :min="1"
              :precision="0"
              :disabled="scene == 3"
            />
            <i
              class="el-icon-info icon"
              style="color: #c3c3c3; font-size: 16px; margin: 0 5px 0 10px"
            ></i>
            <span class="hint">连续n个监控周期的采样值全部满足触发条件</span>
          </el-row>
        </el-form-item>
        <el-form-item label="执行动作" prop="num">
          <el-row type="flex" align="middle">
            <div class="text" style="margin-left: 0">减少</div>
            <el-input-number
              v-model="formMin.num"
              placeholder="请输入"
              style="width: 160px"
              :min="1"
              :max="maxNumUpper - 1"
              :precision="0"
              :disabled="scene == 3"
            />
            <div class="text" style="margin-right: 0">个实例</div>
            <i
              class="el-icon-info icon"
              style="color: #c3c3c3; font-size: 16px; margin: 0 5px 0 10px"
            ></i>
            <span class="hint">一次最多可以触发该伸缩组配置最大VM数-1</span>
          </el-row>
        </el-form-item>
        <el-form-item label="冷却时间(s)" prop="coolTime">
          <el-row type="flex" align="middle">
            <el-input
              v-model="formMin.coolTime"
              placeholder="请输入"
              style="width: 200px; flex-shrink: 0"
              :disabled="scene == 3"
            />
            <i
              class="el-icon-info icon"
              style="color: #c3c3c3; font-size: 16px; margin: 0 5px 0 10px"
            ></i>
            <span
              class="hint"
            >每次伸缩完成之后，系统计算冷区时间，在此期间内拒绝再次触发伸缩活动</span>
          </el-row>
        </el-form-item>
      </el-form>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button size="small" @click="cancelClick">取 消</el-button>
      <el-button
        type="primary"
        size="small"
        :loading="confirmLoading"
        @click="confirmClick"
      >确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { addScalingPolicy } from '@/api/cnap/hybrid-cloud'

export default {
  name: 'ScalingPolicyDialog',
  props: {
    // 显示
    show: {
      type: Boolean,
      default: false
    },
    // 场景
    scene: {
      type: Number,
      default: 1 // 1-创建 2-编辑 3-查看
    },
    // 传递数据
    info: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    /**
     * @description: 校验触发条件
     * @param {*} rule
     * @param {*} value
     * @param {*} callback
     * @return {*}
     */
    var validateTriggerCondition = (rule, value, callback) => {
      if (!this.formMax.resource) {
        callback(new Error('请选择触发条件')) // 抛出异常
      } else if (
        !(
          parseInt(this.formMax.value) > 0 && parseInt(this.formMax.value) < 100
        )
      ) {
        // 校验触发条件最大值
        callback(new Error('触发条件数值只能为0~100之间的整数')) // 抛出异常
      } else {
        callback()
      }
    }
    /**
     * @description: 校验触发条件
     * @param {*} rule
     * @param {*} value
     * @param {*} callback
     * @return {*}
     */
    var validateTriggerCondition2 = (rule, value, callback) => {
      if (!this.formMin.resource) {
        callback(new Error('请选择触发条件')) // 抛出异常
      } else if (
        !(
          parseInt(this.formMin.value) > 0 && parseInt(this.formMin.value) < 100
        )
      ) {
        // 校验触发条件最小值
        callback(new Error('触发条件数值只能为0~100之间的整数')) // 抛出异常
      } else {
        if (this.showPolicyMax) {
          // 也选择了扩容策略
          if (this.formMax.resource !== this.formMin.resource) {
            callback(new Error('扩容策略和缩容策略的触发条件需要一致')) // 抛出异常
          } else if (Number(this.formMax.value) <= Number(this.formMin.value)) {
            callback(new Error('最大值的下限要大于最小值的上限')) // 抛出异常
          } else {
            callback()
          }
        } else {
          callback()
        }
      }
    }
    return {
      title: '创建伸缩策略', // 标题
      confirmLoading: false,
      maxNumUpper: 11,
      showPolicyMax: false, // 是否展示扩容策略
      showPolicyMin: false, // 是否展示缩容策略
      // 触发条件选项
      resourceOptions: [
        {
          lable: 'CPU使用率',
          value: 'cpu'
        },
        {
          lable: '内存使用率',
          value: 'memory'
        }
      ],
      // 监控周期选项
      durationOptions: [
        {
          lable: '5',
          value: '5'
        },
        {
          lable: '10',
          value: '10'
        },
        {
          lable: '15',
          value: '15'
        }
      ],
      // 表单
      formMax: {
        resource: '', // 资源，cpu memory
        value: '',
        duration: '', // 监控周期（分钟）
        continuousNum: '', // 连续出现次数
        num: '', // 扩缩容数量
        coolTime: '' // 冷却时间（秒）
      },
      // 表单
      formMin: {
        resource: '', // 资源，cpu，memory
        value: '',
        duration: '', // 监控周期（分钟）
        continuousNum: '', // 连续出现次数
        num: '', // 扩缩容数量
        coolTime: '' // 冷却时间（秒）
      },
      // 校验规则
      rules: {
        // 触发条件
        triggerCondition: [
          { required: true, validator: validateTriggerCondition }
        ],
        // 触发条件2
        triggerCondition2: [
          { required: true, validator: validateTriggerCondition2 }
        ],
        // 监控周期
        duration: [
          { required: true, message: '请选择监控周期', trigger: 'change' }
        ],
        continuousNum: [{ required: true, message: '请输入连续出现次数' }], // 连续出现次数
        num: [{ required: true, message: '请输入执行实例个数' }], // 执行实例个数
        // 冷却时间
        coolTime: [
          { required: true, pattern: /^([0-9]*)$/, message: '请输入整数' }
        ]
      }
    }
  },
  watch: {
    /**
     * @description: 监听场景
     * @return {*}
     */
    scene: {
      handler(newVal) {
        if (newVal === 1) {
          // 创建
          this.title = '创建伸缩策略'
          this.showPolicyMax = false // 扩容策略 不展示
          this.showPolicyMin = false // 缩容策略 不展示
        } else if (newVal === 2) {
          // 编辑
          this.title = '编辑伸缩策略'
          this.initForm(newVal)
        } else if (newVal === 3) {
          // 查看
          this.title = '查看伸缩策略'
          this.initForm(newVal)
        }
      },
      immediate: true
    }
  },
  methods: {
    /**
     * @description: 初始化form
     * @param {*} scene
     * @return {*}
     */
    initForm(scene) {
      // 编辑 或者 查看
      if (scene === 2 || scene === 3) {
        // 查找是否配置了扩容策略
        const maxIndex = this.info.policyInfos.findIndex((item) => {
          return item.type === 'max'
        })
        // 查找是否配置了缩容策略
        const minIndex = this.info.policyInfos.findIndex((item) => {
          return item.type === 'min'
        })
        if (maxIndex > -1) {
          // 配置了扩容策略
          this.showPolicyMax = true // 扩容策略 展示
          this.formMax = {
            resource: this.info.policyInfos[maxIndex].resource,
            value: this.info.policyInfos[maxIndex].value,
            duration: this.info.policyInfos[maxIndex].duration,
            continuousNum: this.info.policyInfos[maxIndex].continuousNum,
            num: this.info.policyInfos[maxIndex].num,
            coolTime: this.info.policyInfos[maxIndex].coolTime
          }
        } else {
          // 没配置
          this.showPolicyMax = false // 扩容策略 不展示
        }
        if (minIndex > -1) {
          // 配置了缩容策略
          this.showPolicyMin = true // 缩容策略 展示
          this.formMin = {
            resource: this.info.policyInfos[minIndex].resource,
            value: this.info.policyInfos[minIndex].value,
            duration: this.info.policyInfos[minIndex].duration,
            continuousNum: this.info.policyInfos[minIndex].continuousNum,
            num: this.info.policyInfos[minIndex].num,
            coolTime: this.info.policyInfos[minIndex].coolTime
          }
        } else {
          this.showPolicyMin = false // 缩容策略 不展示
        }
      }
    },
    /**
     * @description: 删除策略按钮
     * @param {*} type
     * @return {*}
     */
    deletePolicyClick(type) {
      if (type === 'max') {
        // 扩容
        this.showPolicyMax = false
      } else if (type === 'min') {
        // 缩容
        this.showPolicyMin = false
      }
    },
    /**
     * @description: 新增策略按钮
     * @param {*} type
     * @return {*}
     */
    addPolicyClick(type) {
      if (type === 'max') {
        // 扩容
        this.showPolicyMax = true
      } else if (type === 'min') {
        // 缩容
        this.showPolicyMin = true
      }
    },
    /**
     * @description: 新增策略
     * @param {*} params
     * @return {*}
     */
    addPolicy(params) {
      this.confirmLoading = true
      // 新增
      addScalingPolicy(params)
        .then((res) => {
          this.$emit('update:show', false)
          this.$emit('success') // 事件回调
        })
        .finally(() => {
          this.confirmLoading = false
        })
    },
    /**
     * @description: 确定
     * @return {*}
     */
    confirmClick() {
      if (this.scene !== 1 && this.scene !== 2) {
        // 不是创建和编辑 直接取消
        this.$emit('update:show', false)
        return
      }
      if (!this.showPolicyMax && !this.showPolicyMin) {
        // 没有添加策略
        this.$message.warning('请新增扩缩容策略')
        return
      } else if (this.showPolicyMax && !this.showPolicyMin) {
        // 添加了扩容策略
        this.$refs.formMax.validate((valid, obj) => {
          if (valid) {
            // 新增一个策略
            this.addPolicy([
              {
                type: 'max', // 策略类型
                groupId: this.info.groupId, // 伸缩组id
                ...this.formMax // 表单
              }
            ])
          }
        })
      } else if (!this.showPolicyMax && this.showPolicyMin) {
        // 添加了缩容策略
        this.$refs.formMin.validate((valid, obj) => {
          if (valid) {
            // 新增一个策略
            this.addPolicy([
              {
                type: 'min', // 策略类型
                groupId: this.info.groupId, // 伸缩组id
                ...this.formMin // 表单
              }
            ])
          }
        })
      } else if (this.showPolicyMax && this.showPolicyMin) {
        // 添加了扩容策略和缩容策略
        this.$refs.formMax.validate((valid, obj) => {
          if (valid) {
            this.$refs.formMin.validate((valid2, obj) => {
              if (valid2) {
                // 新增两个策略
                this.addPolicy([
                  {
                    type: 'max', // 策略类型
                    groupId: this.info.groupId, // 伸缩组id
                    ...this.formMax // 表单
                  },
                  {
                    type: 'min', // 策略类型
                    groupId: this.info.groupId, // 伸缩组id
                    ...this.formMin // 表单
                  }
                ])
              }
            })
          }
        })
      }
    },
    /**
     * @description: 关闭
     * @return {*}
     */
    closeClick() {
      this.$emit('update:show', false)
    },
    /**
     * @description: 取消
     * @return {*}
     */
    cancelClick() {
      this.closeClick()
      this.$emit('cancel') // 事件回调
    }
  }
}
</script>

<style lang="less" scoped>
@import "@/assets/css/common.less";
.scaling-policy-dialog {
  .wrapper {
    background: #fdfdfd;
    border: 1px solid #ececec;
    box-sizing: border-box;
    padding: 10px 20px;
    margin-top: 15px;

    .divider {
      margin: 5px 0 10px 0;
      background: #f2f2f2;
    }

    .text {
      .textStyle(14px , 400, #4a4a4a);
      line-height: 20px;
      margin: 0 15px;
    }

    .hint {
      .textStyle(12px , 400, #C3C3C3);
      line-height: 18px;
    }
  }
}
</style>
